package cn.mrlong.base.utils

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.wifi.WifiManager
import android.telephony.TelephonyManager
import androidx.core.app.ActivityCompat
import cn.mrlong.base.extensions.isBlank
import java.lang.reflect.Method
import java.util.*

/**
 * 作者：BINGO
 * 时间：2021/04/16 10:02
 */
object DeviceId {
    private const val tag = "android_device_id"
    private const val ANDROID_DEVICE_ID = "ANDROID_DEVICE_ID"
    private const val KEY = "UUID"
    private var uuid: String? = null
    fun getDeviceId(context: Context): String {
        try {
            //IMEI
            val imeiSingle = getImei(context)
            if (null != imeiSingle) return imeiSingle
            val imeiDouble = getImeiFromDoubleSIM(context)
            if (null != imeiDouble) return imeiDouble
            val sn = getSim(context)
            if (null != sn) return sn
            //val wifiMac = getWifiMac(context)
            //if (null != wifiMac) return wifiMac
            val uid = getUUID(context)
            if (null != uid) return uid
        } catch (e: Exception) {
            e.printStackTrace()
            val uid = getUUID(context)
            if (null != uid) return uid
        }
        return ""
    }

   private fun getUUID(context: Context): String? {
        val share = getSysShare(context)
        uuid = share?.getString(KEY, null)
        if (String.isBlank(uuid)) {
            uuid = UUID.randomUUID().toString().replace("-", "")
            saveSysMap(context, ANDROID_DEVICE_ID, KEY, uuid!!)
        }
        return uuid
    }

    private fun saveSysMap(context: Context, androidDeviceId: String, key: String, uuid: String) {
        val sp = context.getSharedPreferences(androidDeviceId,Context.MODE_PRIVATE)
        sp.edit().putString(key,uuid).apply()
    }

    private fun getSysShare(context: Context): SharedPreferences? {
        return context.getSharedPreferences(ANDROID_DEVICE_ID, Context.MODE_PRIVATE);
    }

    @SuppressLint("HardwareIds")
    private fun getWifiMac(context: Context): String? {
        val wifi = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
        return wifi.connectionInfo?.macAddress
    }

    @SuppressLint("MissingPermission", "HardwareIds")
    private fun getSim(context: Context): String? {
        val tm =
            context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        if (ActivityCompat.checkSelfPermission(
                context.applicationContext,
                Manifest.permission.READ_PHONE_STATE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            return null
        }
        return tm.simSerialNumber
    }

    @SuppressLint("MissingPermission", "HardwareIds")
    private fun getImei(context: Context): String? {
        try {
            val tm =
                context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            if (ActivityCompat.checkSelfPermission(
                    context.applicationContext,
                    Manifest.permission.READ_PHONE_STATE
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                return null
            }
            val imei = tm.getDeviceId()
            return imei
        } catch (e: Exception) {

            return null
        }
    }

    private fun getImeiFromDoubleSIM(context: Context, whichOne: Int = 1): String? {
        return try {
            val manager =
                context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            if (ActivityCompat.checkSelfPermission(
                    context.applicationContext,
                    Manifest.permission.READ_PHONE_STATE
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                return null
            }
            val method: Method = manager.javaClass.getMethod("getImei", Int::class.java)
            method.invoke(manager, whichOne) as String
        } catch (e: java.lang.Exception) {
            ""
        }
    }
}